package com.lzx.adx.report.controller.v1.cps.meituan;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lzs.adx.commmon.utils.DateUtils;
import com.lzs.adx.commmon.utils.JsonUtils;
import com.lzs.adx.commmon.utils.Result;
import com.lzx.adx.report.bean.mapper.MeiTuanMapper;
import com.lzx.adx.report.bean.mapper.ReportMapper;
import com.lzx.adx.report.cache.AccountLocalCache;
import com.lzx.adx.report.dto.AccountDTO;
import com.lzx.adx.report.dto.MeituanOrderDTO;
import com.lzx.adx.report.dto.ReportDTO;
import com.lzx.adx.report.dto.meituan.MeiTuanResponse;
import com.lzx.adx.report.entity.MeituanOrderEntity;
import com.lzx.adx.report.enums.EventTypeEnums;
import com.lzx.adx.report.model.huawei.request.HwUploadRequest;
import com.lzx.adx.report.model.meituan.OrderCallBackRequest;
import com.lzx.adx.report.service.MeituanOrderService;
import com.lzx.adx.report.service.ReportService;
import com.lzx.adx.report.util.HwSecureUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

@RequestMapping("/meituan")
@RestController
@Slf4j
public class CallBackController {

    @Resource
    private MeituanOrderService meituanOrderService;

    @Autowired
    private MeiTuanMapper tuanMapper;

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private ThreadPoolTaskExecutor reportExecutor;

    @Resource
    private ReportService reportService;



    /**
     * 接收订单推送的接口
     * @return
     */
    @RequestMapping("/callBack")
    public MeiTuanResponse orderCallBack(@RequestBody OrderCallBackRequest orderCallBackRequest){
        log.info("接收到【快手美团】的请求参数为{}", JsonUtils.toJsonString(orderCallBackRequest));
        try {
            String sid = orderCallBackRequest.getSid();
            Map<String, Object> map = new HashMap<>();
            map.put("orderId", orderCallBackRequest.getOrderid());
            map.put("handType", true);
            map.put("limit", true);
            List<MeituanOrderDTO> meituanOrderDTOList = meituanOrderService.list(map);
            if (CollectionUtil.isNotEmpty(meituanOrderDTOList)) {
                log.info("dspId:{} 订单号:{} 已经处理过了无需再处理", sid, orderCallBackRequest.getOrderid());
                return new MeiTuanResponse().ok();
            }
            //先吧数据存储起来
            MeituanOrderDTO meituanOrderDTO = tuanMapper.toMeituanOrder(orderCallBackRequest);
            meituanOrderDTO.setTradeTypes(StringUtils.join(orderCallBackRequest.getTradeType(), ","));
            meituanOrderDTO.setCreateTime(new Date());
            meituanOrderDTO.setUpdateTime(new Date());
            meituanOrderDTO.setExtend(JSON.toJSONString(orderCallBackRequest));
            meituanOrderService.save(meituanOrderDTO);

            //根据时间点去推送
            String paytime = meituanOrderDTO.getPaytime();
            //广告位id
            //请求参数
            Map<String, Object> params = new HashMap<>();
            params.put("ordertime", DateUtils.convertToFormattedDate(Long.parseLong(paytime)));
            params.put("dsp_id", sid);
            params.put("resultType", true);
            params.put("limit", true);
            List<ReportDTO> list = reportService.list(params);
            if (CollectionUtil.isEmpty(list)) {
                log.info("dspId:{} 订单号:{} 未匹配到合适的点击", sid, orderCallBackRequest.getOrderid());
                return new MeiTuanResponse().ok();
            }
            ReportDTO reportDTO = list.get(0);
            AccountDTO accountDTO = AccountLocalCache.getInstance().get(sid);
            if (null == accountDTO) {
                log.info("dspId:{} 订单号:{} 未匹配到合适的广告位", sid, orderCallBackRequest.getOrderid());
                return new MeiTuanResponse().ok();
            }
            if (accountDTO.getProduct().equals("ks")) {
                ksCallback(orderCallBackRequest, reportDTO);
            } else if (accountDTO.getProduct().equals("toutiao")) {
                toutiao(orderCallBackRequest, reportDTO);
            } else if (accountDTO.getProduct().equals("hwMt")) {
                huawei(orderCallBackRequest, reportDTO);
            } else {
                log.error("媒体未配置");
                return new MeiTuanResponse().ok();
            }
            String eventType = "3";
            //和点击追踪绑定
            String value = String.valueOf(System.currentTimeMillis());
            reportDTO.setResultType(eventType);
            reportDTO.setResultTime(value);
            reportDTO.setSid(orderCallBackRequest.getSid());
            reportDTO.setAppkey(orderCallBackRequest.getAppkey());
            reportDTO.setActId(orderCallBackRequest.getActId());
            reportDTO.setUpdateTime(new Date());
            reportService.updateData(reportDTO,eventType);
            //更新订单状态标识已推送
            updateOrderStatus(meituanOrderDTO.getId());
            log.info("dspId:{} 订单号:{} 处理成功", sid, orderCallBackRequest.getOrderid());
        } catch (Exception e) {
            log.error("快手美团 出现异常的 dspId:{} 订单号为{} ", orderCallBackRequest.getSid(), orderCallBackRequest.getOrderid());
            log.error("快手美团 处理快手-美团出现了异常，异常的错误为", e);
        }
        return new MeiTuanResponse().ok();
    }

    private void huawei(OrderCallBackRequest orderCallBackRequest, ReportDTO reportDTO) {
        Long eventTime;
        if (StringUtils.isNotBlank(orderCallBackRequest.getOrdertime())) {
            eventTime = Long.parseLong(orderCallBackRequest.getOrdertime()) * 1000;
        } else {
            eventTime = Long.parseLong(orderCallBackRequest.getPaytime()) * 1000;
        }
        reportDTO.setResultType(String.valueOf(eventTime));
        AccountDTO accountDTO = AccountLocalCache.getInstance().get(reportDTO.getDspId());

        log.info("从数据库查询的数据为{}",JsonUtils.toJsonString(reportDTO));
        //2.回调渠道，调用华为回传接口
        Long conversion_time=System.currentTimeMillis()/1000;
        HwUploadRequest hwUploadRequest=new HwUploadRequest();
        hwUploadRequest.setOaid(reportDTO.getOaid());
        hwUploadRequest.setConversion_type("paid");
        hwUploadRequest.setTimestamp(String.valueOf(System.currentTimeMillis()));
        hwUploadRequest.setCallback(reportDTO.getCallback());
        hwUploadRequest.setCampaign_id(reportDTO.getCampaignId());
        hwUploadRequest.setContent_id(reportDTO.getContentId());

        hwUploadRequest.setConversion_time(String.valueOf(conversion_time));
        hwUploadRequest.setTracking_enabled("1");
        String paramsBody = JsonUtils.toJsonString(hwUploadRequest);

        log.info("账号为【{}】，mt给华为请求的参数为{}",reportDTO.getDspId(),paramsBody);
        Map<String,String> header=new HashMap<>();

        header.put("Authorization", HwSecureUtil.buildAuthorizationHeader(paramsBody,accountDTO.getSspKey()));

        HttpRequest body = HttpUtil.createPost(accountDTO.getSspApiUrl()).addHeaders(header).body(paramsBody);
        String result = body.execute().body();
        log.info("账号为【{}】，mt接收华为转换响应的结果为{}",reportDTO.getDspId(),result);
    }


    /**]
     *
     * @param orderCallBackRequest
     * @param reportDTO
     */
    public void ksCallback(OrderCallBackRequest orderCallBackRequest,ReportDTO reportDTO){
        //2.从缓存加载配置
        AccountDTO accountDTO = AccountLocalCache.getInstance().get(reportDTO.getDspId());
        String dspSalt = accountDTO.getDspSalt();
        Long eventTime;
        if (StringUtils.isNotBlank(orderCallBackRequest.getOrdertime())) {
            eventTime = Long.parseLong(orderCallBackRequest.getOrdertime()) * 1000;
        } else {
            eventTime = Long.parseLong(orderCallBackRequest.getPaytime()) * 1000;
        }
        //2.回调渠道，调用快手回传接口
        Map<String, Object> reqParams = new HashMap<>();
        reqParams.put("event_type", dspSalt);
        reqParams.put("event_time", eventTime);
        reqParams.put("purchase_amount", Double.valueOf(orderCallBackRequest.getTotal()));
        //组装参数和url
        String urlParams = URLUtil.buildQuery(reqParams, StandardCharsets.UTF_8);
        String finalReqUrl = reportDTO.getCallback() + "&" + urlParams;
        log.info("账户号【{}】，快手美团-进行快速回调的请求参数为{}", reportDTO.getDspId(), finalReqUrl);
        String result = HttpUtil.createGet(finalReqUrl).execute().body();
        log.info("账户号【{}】，快手美团-转换响应的结果为-{}", reportDTO.getDspId(), result);



    }

    public void toutiao(OrderCallBackRequest orderCallBackRequest,ReportDTO reportDTO){
        //2.从缓存加载配置
        AccountDTO accountDTO = AccountLocalCache.getInstance().get(reportDTO.getDspId());
        String dspSalt = accountDTO.getDspSalt();


        //2.回调渠道，调用快手回传接口
        Map<String, Object> reqParams = new HashMap<>();
        reqParams.put("event_type", dspSalt);
        //组装参数和url
        String urlParams = URLUtil.buildQuery(reqParams, StandardCharsets.UTF_8);
        String finalReqUrl = reportDTO.getCallback() + "&" + urlParams;
        log.info("账户号【{}】，头条美团 进行快速回调的请求参数为{}", reportDTO.getDspId(), finalReqUrl);
        String result = HttpUtil.createGet(finalReqUrl).execute().body();
        log.info("账户号【{}】，头条美团 的转换响应的结果为-{}", reportDTO.getDspId(), result);
    }



    public void updateOrderStatus(Long id){
        //更新订单状态为已处理
        MeituanOrderEntity meituanOrderEntity = new MeituanOrderEntity();
        meituanOrderEntity.setId(id);
        meituanOrderEntity.setHandType(1);
        meituanOrderService.updateById(meituanOrderEntity);
    }
}
